/*-------------------------------------------------------------------------
 *
 * copy.h
 *	  使用 POSTGRES 复制命令的定义。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/commands/copy.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef COPY_H
#define COPY_H

#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "tcop/dest.h"

/*
 * 表示标题行是否应存在，以及是否必须与实际名称匹配（这意味着“真”）。
 */
typedef enum CopyHeaderChoice
{
	COPY_HEADER_FALSE = 0,
	COPY_HEADER_TRUE,
	COPY_HEADER_MATCH,
} CopyHeaderChoice;

/*
 * 用于保存 COPY 选项的结构，解析后的形式。除了 'freeze' 之外，所有这些选项都与格式相关，
 * 'freeze' 实际上不属于这里，但将它与其他选项一起解析是方便的。
 */
typedef struct CopyFormatOptions
{
	/* COPY 命令的参数 */
	int			file_encoding;	/* 文件或远程端的字符编码，
								 * -1 如果未指定 */
	bool		binary;			/* 二进制格式？ */
	bool		freeze;			/* 加载时是否冻结行？ */
	bool		csv_mode;		/* 逗号分隔值格式？ */
	CopyHeaderChoice header_line;	/* 标头行？ */
	char	   *null_print;		/* NULL 标记字符串（服务器编码！） */
	int			null_print_len; /* 同样的长度 */
	char	   *null_print_client;	/* 转换为文件编码后相同 */
	char	   *delim;			/* 列分隔符（必须是1字节） */
	char	   *quote;			/* CSV引号字符（必须是1字节） */
	char	   *escape;			/* CSV转义字符（必须是1字节） */
	List	   *force_quote;	/* 列名称列表 */
	bool		force_quote_all;	/* FORCE_QUOTE *? */
	bool	   *force_quote_flags;	/* 每列CSV FQ标志 */
	List	   *force_notnull;	/* 列名称列表 */
	bool	   *force_notnull_flags;	/* 每列CSV FNN标志 */
	List	   *force_null;		/* 列名称列表 */
	bool	   *force_null_flags;	/* 每列CSV FN标志 */
	bool		convert_selectively;	/* 是否进行选择性二进制转换？ */
	List	   *convert_select; /* 列名称列表（可以为NIL） */
} CopyFormatOptions;

/* 这些在commands/copy[from|to].c中是私有的 */
typedef struct CopyFromStateData *CopyFromState;
typedef struct CopyToStateData *CopyToState;

typedef int (*copy_data_source_cb) (void *outbuf, int minread, int maxread);

extern void DoCopy(ParseState *state, const CopyStmt *stmt,
				   int stmt_location, int stmt_len,
				   uint64 *processed);

extern void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *ops_out, bool is_from, List *options);
extern CopyFromState BeginCopyFrom(ParseState *pstate, Relation rel, Node *whereClause,
								   const char *filename,
								   bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options);
extern void EndCopyFrom(CopyFromState cstate);
extern bool NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
						 Datum *values, bool *nulls);
extern bool NextCopyFromRawFields(CopyFromState cstate,
								  char ***fields, int *nfields);
extern void CopyFromErrorCallback(void *arg);

extern uint64 CopyFrom(CopyFromState cstate);

extern DestReceiver *CreateCopyDestReceiver(void);

/*
 * 内部原型
 */
extern CopyToState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *query,
							   Oid queryRelId, const char *filename, bool is_program,
							   List *attnamelist, List *options);
extern void EndCopyTo(CopyToState cstate);
extern uint64 DoCopyTo(CopyToState cstate);
extern List *CopyGetAttnums(TupleDesc tupDesc, Relation rel,
							List *attnamelist);

#endif							/* COPY_H */
